#include<iostream>

#include<cstdio>
#include<string>
#include<cstdlib>
#include<cstring>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
using namespace std;
const int basesize=1024;
int argc=0;
const int argvnum=64;
char *argv[argvnum];
const int envnum=64;
char *genv[envnum];
const int pwdnum=255;
char pwd[pwdnum];
char pwdenv[pwdnum];
void InitEnv()//初始化环境变量
{
  extern char**environ;
  int i=0;
  for(;environ[i];i++)
  {
    genv[i]=(char*)malloc(strlen(environ[i])+1);
    strncpy(genv[i],environ[i],strlen(environ[i])+1);
  }
  genv[i]=nullptr;
}


//[lisi@VM-8-16-centos lesson6]$
    //命令行
string GetUserName()
{
  string name=getenv("USER");
  return name.empty()?"None":name;
}
string GetHostName()
{
  string hostname=getenv("HOSTNAME");
  return hostname.empty()?"None":hostname;
}
string GetPwdName()
{
  if(nullptr==getcwd(pwd,sizeof(pwd))) return "None";
  snprintf(pwdenv,sizeof(pwdenv),"PWD=%s",pwd);
  putenv(pwdenv);
  return pwd;
 //string pwdname=getenv("PWD");
}
string MakeCommandLine()
{
  char CommandLine[basesize];
  snprintf(CommandLine,basesize,"[%s@%s %s]$",\
      GetUserName().c_str(),GetHostName().c_str(),GetPwdName().c_str());
  return CommandLine;

}
void PrintCommandLine()
{
    printf("%s",MakeCommandLine().c_str());
    fflush(stdout);
}
bool GetCommandLine(char command_buffer[],int size)
{
  char*result=fgets(command_buffer,size,stdin);
  if(!result)
  { 
    return false;
  }
    command_buffer[strlen(command_buffer)-1]=0;
  return true;
}

void ParseCommandLine(char command_buffer[],int size)
{
  memset(argv,0,argvnum);
  argc=0;
  (void)size;
  char pek[]=" ";
  argv[argc++]=strtok(command_buffer,pek);
  while((bool)(argv[argc++]=strtok(nullptr,pek)));
  argc--;
}

bool  ExcuteCommandLine()
{
  pid_t id=fork();
  if(id==0)
  {
    execvpe(argv[0],argv,genv);
    exit(1);
  }
  pid_t rid=waitpid(id,nullptr,0);
  if(rid>0) return true;
  return false;
}
void AddEnd(const char*item)
{
  int index=0;
  while(genv[index])
  {
    index++;
  }
  genv[index]=(char*)malloc(strlen(item)+1);
  strncpy(genv[index],item,strlen(item)+1);
  genv[++index]=nullptr;
}
void checkenv()
{
  for(int i=0;genv[i];i++)
    printf("%s\n",genv[i]);
}
 bool CheckAndExcuBuitCommand()
{
    if(strcmp(argv[0],"cd")==0)
    {
      if(argc==2)
      {
        chdir(argv[1]);
      }
      return true;
    }else if(strcmp(argv[0],"export")==0)
    {
      if(argc==2)
      {
        AddEnd(argv[1]);
      }
      return true;
    }else if(strcmp(argv[0],"env")==0)
    {
      checkenv();
      return true;
    }

    return false;
}
int main()
{
  InitEnv();
  char command_buffer[basesize];
  while(true)
  {
    //命令行
    PrintCommandLine();
    //获取命令行
   if(!GetCommandLine(command_buffer,basesize))
   {
     continue;
   }
    ////分析命令行
    ParseCommandLine(command_buffer,strlen(command_buffer));
   //if(argv[0]=="cd")
   //{
   //  //建内函数
   //  chdir(argv[1]);
   //  continue;
   //}
   // for(int i=0;i<argc;i++)
   // {
   //   printf("argv[%d]:%s\n",i,argv[i]);
   // }
    if(CheckAndExcuBuitCommand())
    {
        continue;
    }
    ExcuteCommandLine();//执行命令行

  }


  return 0;
}
